from functools import wraps
from app.models.datasets import DEFAULT_DATASET
from google.appengine.api import users
from app.models.permissions import PERMISSIONS, get_permissions_for

##################### GENERAL PERMISSIONS STUFF ##############################

class RequiresPermission(object):
  """ A decorator for RequestHandler methods that require a permission
  
  Decorator accepts string specifying which permission are required
  If no string specified, then simply requires a login. Also assigns
  current user to self.user
  
  """
  def __init__(self, permission=None):
    if permission:
      assert permission in PERMISSIONS, "Permission should be added to list"
    self.permission = permission
  
  def __call__(self, func):
    """ Rewriting the __call__ method makes class act like function """
    permission = self.permission
    
    @wraps(func)
    def _decorated(self, *args, **kwargs):
      # Check login status first
      user = users.get_current_user()
      if user:
        self.user = user
        self.dataset = DEFAULT_DATASET
        # Next check permission
        if ((not permission) or
            users.is_current_user_admin() or
            permission in get_permissions_for(user)):
          return func(self, *args, **kwargs)
        
        else: # No permission!
          self.redirect('/access/nopermission')
        
      else: # Not logged in!
        self.redirect(users.create_login_url(self.request.uri))
      
    return _decorated

class RequiresAdmin(RequiresPermission):
  """ Admins only decorator -- equivalent to having an 'admin' permission """
  def __init__(self):
    self.permission = '**ADMIN**'

# Lower underscore case is more function like
requires_permission = RequiresPermission
requires_login = RequiresPermission()
requires_admin = RequiresAdmin()

